import sys

sys.path.append("..")

try:
    from CoreSim.Unit import *
    from CoreSim.Simulator import *
    from CoreSim.SchedulerHybrid import *
except:
    raise


def MakeFlows(_flowsFileName, _numHosts, _numLinks, _numToRs, _trafficType):
    f = open(inDir + _flowsFileName, "w")
    if _trafficType == "random":
        for i in xrange(0, _numToRs):
            for j in xrange(0, _numHosts):
                while True:
                    i_remote = random.randint(0, _numToRs - 1)
                    if i_remote != i:
                        break
                j_remote = random.randint(0, _numHosts - 1)

                Host_id = _numHosts * i + j + 1
                Host_remote_id = _numHosts * i_remote + j_remote + 1
                print >> f, Host_id, Host_remote_id

    elif _trafficType == "host_stride":
        stride = 20
        for i in xrange(0, _numToRs):
            for j in xrange(0, _numHosts):
                Host_id = _numHosts * i + j + 1
                Host_remote_id = (Host_id + stride) % (_numHosts * _numToRs) + 1
                if Host_remote_id == Host_id:
                    Host_remote_id += 1
                print >> f, Host_id, Host_remote_id

    elif _trafficType == "tor_stride":
        stride = 4
        for i in xrange(0, _numToRs):
            for j in xrange(0, _numHosts):
                while True:
                    i_remote = random.randint(0, _numToRs - 1)
                    if i_remote != i:
                        break

                Host_id = _numHosts * i + j + 1
                Host_remote_id = (_numHosts * (i + stride) + j) % (_numHosts * _numToRs) + 1
                if Host_remote_id == Host_id:
                    Host_remote_id += 1
                print >> f, Host_id, Host_remote_id

    elif _trafficType == "cluster":
        pass

    elif _trafficType == "permutation":
        pass

    f.close()


if __name__ == "__main__":

    numToRs = 64
    numHosts = 16
    numLinks = 10
    numSLinks = 2
    link_sh_Bw = 10.0 * Gb
    link_ss_Bw = 10.0 * Gb

    trafficTypes = ['host_stride']  # 'stride', 'random'
    schedulers = ['Detour', 'OSA', 'OvS', 'Jelly']

    flowsDir = 'Static/'

    topoDir = 'Static/'
    s_topoFileName = "topo_%sToRs_%sHosts_%sLinks_%sSLinks_static.txt" \
                     % (numToRs, numHosts, numLinks, numSLinks)
    d_topoFileName = "topo_%sToRs_%sHosts_%sLinks_%sSLinks_dynamic.txt" \
                     % (numToRs, numHosts, numLinks, numSLinks)

    for trafficType in trafficTypes:

        flowsFileName = "%s_%sToRs_%sHosts_%sLinks.txt" \
                        % (trafficType, numToRs, numHosts, numLinks)
        flowsFileName = flowsDir + flowsFileName

        if not os.path.exists(inDir + flowsDir):
            os.makedirs(inDir + flowsDir)

        if not os.path.isfile(inDir + flowsFileName):
            MakeFlows(flowsFileName, numHosts, numLinks, numToRs, trafficType)

        for scheduler in schedulers:

            sim = Simulator()
            sim.AssignSdnScheduler(Scheduler=SchedulerHybrid(numLinks, numSLinks, numHosts, numToRs, link_ss_Bw,
                                                             scheduler, k=2), args=(trafficType, flowsFileName))

            sim.sched.InitialTopology(topoDir, s_topoFileName, d_topoFileName)
            sim.sched.CalBandwidth()

            if scheduler != 'Jelly':
                sim.sched.Reconfigure_network(scheduler)
                sim.sched.CalBandwidth()
            sim.sched.PrintFlows()
